﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;

namespace deFramework.Base
{
    /// <summary> 
    /// Base SharePoint data access class for reusable SharePoint related methods
    /// </summary>
    /// <remarks> 
    /// These data  access classes should not dispose of the SPWeb object. 
    /// That is taken care of by the Render event in the base page or base web part object 
    /// calling this.MyContext.Dispose which then disposes the SPWeb object. 
    /// </remarks>
    public class BaseSharePointDataAccess
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="aWeb"></param>
        public BaseSharePointDataAccess(ref Microsoft.SharePoint.SPWeb aWeb)
        {
            this.MySpWeb = aWeb;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public string GetWebProperty(string propertyName, string defaultValue)
        {
            string result = defaultValue;
            try
            {
                result = this.MySpWeb.Properties[propertyName];
            }
            catch { } // no exception handling needed 
            return result; 
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetWebProperty(string propertyName, string value)
        {
            bool result = false;
            try
            {
                this.MySpWeb.Properties[propertyName] = value;
                result = true; 
            }
            catch { } // no exception handling needed 
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        protected Microsoft.SharePoint.SPWeb MySpWeb = null;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fieldsCommaSeparated"></param>
        /// <param name="sourceTable"></param>
        /// <returns></returns>
        protected System.Data.DataTable TransformTableUsingDefinedStringFields(
            string fieldsCommaSeparated, System.Data.DataTable sourceTable)
        {
            System.Data.DataTable newTable = this.NewTableWithDefinedStringFields(fieldsCommaSeparated);
            foreach (System.Data.DataRow sourceRow in sourceTable.Rows)
            {
                System.Data.DataRow newRow = newTable.NewRow();
                try
                {
                    foreach (System.Data.DataColumn column in newTable.Columns)
                    {
                        newRow[column.ColumnName] = sourceRow[column.ColumnName]; 
                    }
                }
                catch { }
                newTable.Rows.Add(newRow);
            }
            return newTable; 
        }

        private System.Data.DataTable NewTableWithDefinedStringFields(
            string fieldsCommaSeparated)
        {
            System.Data.DataTable table = new System.Data.DataTable();
            string[] fieldsList = fieldsCommaSeparated.Split(',');
            foreach (string fieldName in fieldsList)
            {
                System.Data.DataColumn column = new System.Data.DataColumn(fieldName, typeof(System.String));
                table.Columns.Add(column); 
            }
            return table; 
        }

        /// <summary>
        /// Returns a SpList object for the Web Part Gallery for a SpWeb 
        /// regardless of whether or not the SpWeb is the root web or a sub-web.
        /// </summary>
        /// <returns></returns>
        /// <remarks>We need to make this more reusable. Presently it only looks at the context level and its 
        /// parent's level. But it needs to look at N levels up w/o blowing up.</remarks>
        protected Microsoft.SharePoint.SPList WebPartGalleryList()
        {
            Microsoft.SharePoint.SPList webPartGallery = null;
            if (null == this.MySpWeb.ParentWeb)
            {
                // This is the root web.
                webPartGallery = this.MySpWeb.GetCatalog(
                    Microsoft.SharePoint.SPListTemplateType.WebPartCatalog);
            }
            else
            {
                // This is a sub-web.
                webPartGallery = this.MySpWeb.ParentWeb.GetCatalog(
                    Microsoft.SharePoint.SPListTemplateType.WebPartCatalog);
            }
            return webPartGallery;
        }

        /// <summary>
        /// Returns a SPListItemCollection for a particular SPList and a CAML query.
        /// </summary>
        /// <param name="listQuery">the particular SPList to use for the CAML query</param>
        /// <param name="camlQuery"></param>
        /// <returns></returns>
        public Microsoft.SharePoint.SPListItemCollection SpListCamlQueryResults(
            Microsoft.SharePoint.SPList listQuery, string camlQuery)
        {
            Microsoft.SharePoint.SPQuery query = new Microsoft.SharePoint.SPQuery();
            query.Query = camlQuery;
            //query.
            Microsoft.SharePoint.SPListItemCollection listItems =
                listQuery.GetItems(query);  
            return listItems;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="listQuery"></param>
        /// <param name="camlQuery"></param>
        /// <returns></returns>
        public System.Data.DataTable SpListCamlResultsAsTable(
                Microsoft.SharePoint.SPList listQuery, string camlQuery)
        {
            return this.SpListCamlQueryResults(listQuery, camlQuery).GetDataTable(); 
        }


        #region "private - AddWebPartToPageObjectZone, CreateWebPart, ProvisionalAddWebPartObjectToPageObjectZone"


        /// <summary>
        /// Add a new WebPart object to a SPFile object in a specified zone. 
        /// </summary>
        /// <param name="objPage"></param>
        /// <param name="partDefinitionName"></param>
        /// <param name="partInstanceName"></param>
        /// <param name="zoneId"></param>
        /// <param name="zoneIndex"></param>
        /// <returns></returns>
        public bool AddWebPartToPageObjectZone(ref Microsoft.SharePoint.SPFile objPage,
            string partDefinitionName, string partInstanceName, string zoneId, int zoneIndex)
        {
            bool result = false;
            try
            {
                this.MySpWeb.AllowUnsafeUpdates = true;
                this.MySpWeb.Update();
                System.Web.UI.WebControls.WebParts.WebPart newPart =
                    this.CreateWebPart(partDefinitionName);
                newPart.ID = partInstanceName;
                newPart.Title = partInstanceName;
                this.ProvisionalAddWebPartObjectToPageObjectZone(
                    ref objPage, ref newPart, zoneId, zoneIndex);
                result = true;
            }
            finally
            {
                this.MySpWeb.AllowUnsafeUpdates = false;
                this.MySpWeb.Update();
            }
            return result;
        }


        private System.Web.UI.WebControls.WebParts.WebPart CreateWebPart(string webPartName)
        {
            string camlQuery = String.Format(
                "<Where><Eq><FieldRef Name='FileLeafRef'/>" +
                "<Value Type='File'>{0}</Value></Eq></Where>",
                webPartName);
            Microsoft.SharePoint.SPList webPartGallery =
                this.WebPartGalleryList();
            Microsoft.SharePoint.SPListItemCollection webParts =
                this.SpListCamlQueryResults(webPartGallery, camlQuery);
            string typeName = webParts[0].GetFormattedValue("WebPartTypeName");
            string assemblyName = webParts[0].GetFormattedValue("WebPartAssembly");
            System.Runtime.Remoting.ObjectHandle webPartHandle = Activator.CreateInstance(
                assemblyName, typeName);
            System.Web.UI.WebControls.WebParts.WebPart webPart =
                (System.Web.UI.WebControls.WebParts.WebPart)webPartHandle.Unwrap();
            return webPart;
        }



        private void ProvisionalAddWebPartObjectToPageObjectZone(
            ref Microsoft.SharePoint.SPFile page,
            ref System.Web.UI.WebControls.WebParts.WebPart partObject,
            string zoneId, int zoneIndex)
        {
            Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager mgr =
                page.GetLimitedWebPartManager(
                System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
            mgr.AddWebPart(partObject, zoneId, zoneIndex);
            mgr.SaveChanges(partObject);
        }

        #endregion



        #region "SpList Creation or Verification" 

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aListName"></param>
        /// <returns></returns>
        public bool ExistsList(string aListName)
        {
            bool l_Result = false;
            try
            {
                Microsoft.SharePoint.SPList oList = this.MySpWeb.Lists[aListName];
                if (oList != null)
                    l_Result = true;
            }
            catch { }
            return l_Result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aListName"></param>
        /// <param name="aTemplateName"></param>
        /// <returns></returns>
        public Microsoft.SharePoint.SPList CreateListOrGetIfExisting(string aListName, string aTemplateName)
        {
            Microsoft.SharePoint.SPList newList = null;
            bool create = true;
            try
            {
                newList = this.MySpWeb.Lists[aListName];
                if (newList != null)
                {
                    create = false;
                }

            }
            catch (ArgumentException exArg)
            {
                string l_Msg = exArg.Message;
                l_Msg += ".";
            }
            if (create)
            {
                Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    using (Microsoft.SharePoint.SPSite site = new Microsoft.SharePoint.SPSite(this.MySpWeb.Site.ID))
                    {
                        //Guid elevatedId = ; 
                        Microsoft.SharePoint.SPWeb elevatedWeb = site.AllWebs[this.MySpWeb.ID];
                        elevatedWeb.AllowUnsafeUpdates = true;

                        Guid listId = elevatedWeb.Lists.Add(aListName, "", elevatedWeb.ListTemplates[aTemplateName]);
                        newList = elevatedWeb.Lists[listId];

                        elevatedWeb.AllowUnsafeUpdates = false;
                    }
                });

            }
            return newList;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aList"></param>
        /// <param name="aType"></param>
        /// <param name="aName"></param>
        public void AddSpListField(ref Microsoft.SharePoint.SPList aList,
            Microsoft.SharePoint.SPFieldType aType, string aName)
        {
            Microsoft.SharePoint.SPList oList = aList;
            Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(delegate
            {
                using (Microsoft.SharePoint.SPSite site = new Microsoft.SharePoint.SPSite(oList.ParentWeb.Site.ID))
                {
                    Microsoft.SharePoint.SPWeb elevatedWeb = site.AllWebs[oList.ParentWeb.ID];
                    elevatedWeb.AllowUnsafeUpdates = true;
                    Microsoft.SharePoint.SPList myList = elevatedWeb.Lists[oList.ID];

                    myList.Fields.Add(myList.Fields.CreateNewField(aType.ToString(), aName));

                    elevatedWeb.AllowUnsafeUpdates = false;
                }
            });
        }
    


        #endregion 



    }
}
